Spring为任务调度与异步方法执行提供了注解支持。通过在方法上设置@Async注解,可使得方法被异步调用。也就是说调用者会在调用时立即返回,而被调用方法的实际执行是交给Spring的TaskExecutor来完成。
Async示例
定义接口
1 | public interface IDemoService { |
接口实现
1 |
|
示例中分别实现了两个方法: 一个同步调用, 一个异步调用(AsynDemoServiceProxy类中定义了方法的异步实现,这里在并行结果等待场景下,异步逻辑不能和当前主线程处于同一线程中, 负责异步会失效), 代码如下
1 |
|
RestAPI定义
1 |
|
开启@Async支持
SpringMvc处理器xml中配置如下内容
1 | <!-- 支持 @Async 注解 --> |
示例测试
#### 同步调用测试
1 |
|
程序执行结果(约8ms):
1 | MockHttpServletRequest: |
#### 异步调用测试
1 |
|
程序执行结果(约5ms):1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35MockHttpServletRequest:
HTTP Method = GET
Request URI = /api/demo/invoke/asyn
Parameters = {}
Headers = {Content-Type=[application/json;charset=UTF-8], Accept=[application/json;charset=UTF-8]}
Handler:
Type = com.tutorial.spring.async.api.web.controller.AsyncDemoController
Method = public com.tutorial.spring.async.api.result.APIResult com.tutorial.spring.async.api.web.controller.AsyncDemoController.asyn() throws java.lang.Exception
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {M-Appkey=[com.tutorial.spring.async.api], M-SpanName=[AsyncDemoController.asyn], M-Host=[172.30.12.197], Content-Type=[application/json;charset=UTF-8], Content-Length=[126]}
Content type = application/json;charset=UTF-8
Body = {"data":"异步调用: 方法1:耗时:3s方法2:耗时:2s方法3:耗时:3s,总共耗时:5011ms","message":"成功","status":0}
Forwarded URL = null
Redirected URL = null
Cookies = []
{"data":"异步调用: 方法1:耗时:3s方法2:耗时:2s方法3:耗时:3s,总共耗时:5011ms","message":"成功","status":0}
可以明显的看到, 其中串行的一个3ms的耗时被优化.相比于我们自己去定义一个线程体, 然后调用,这样的方式更优雅简单,也利于维护和调整.